﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace ProtocolBuilder.Model.Field
{
    /// <summary>
    /// 协议字段抽象类
    /// </summary>
    public abstract class AbsField
    {
        public AbsField()
        {
            this.Initialize();
        }

        /// <summary>
        /// 持有的xml元素，核心组件，许多其他功能均依赖此对象
        /// </summary>
        public XElement XmlElement
        {
            get;
            set;
        }

        /// <summary>
        /// 字段名称
        /// </summary>
        public string FieldName
        {
            get
            {
                return this.XmlElement.Attribute("name").Value;
            }
            set
            {
                this.XmlElement.Attribute("name").Value = value;
            }
        }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description
        {
            get
            {
                return this.XmlElement.Attribute("description").Value;
            }
            set
            {
                this.XmlElement.Attribute("description").Value = value;
            }
        }

        /// <summary>
        /// 字段类型，如byte/int/short/string等
        /// </summary>
        public string FieldType
        {
            get
            {
                return this.XmlElement.Attribute("type").Value;
            }
            set
            {
                this.XmlElement.Attribute("type").Value = value;
            }
        }

        private void Initialize()
        {
            this.XmlElement = new XElement("field", new XAttribute("name", string.Empty),
                new XAttribute("description", string.Empty),
                new XAttribute("type", string.Empty));
        }

        /// <summary>
        /// 生成缩进
        /// </summary>
        /// <returns></returns>
        protected string GenerateWhiteSpace()
        {
            string prefix = string.Empty;
            int generation = this.GetGeneration();
            for (int i = 0; i < generation; i++)
            {
                prefix += TextHelper.HtmlTab;
            }

            return prefix;
        }

        /// <summary>
        /// 获取嵌套层数
        /// </summary>
        /// <returns></returns>
        protected int GetGeneration()
        {
            int result = -1;    //except the parent is the packet node.
            XElement parent = this.XmlElement.Parent;
            while (parent != null)
            {
                result++;
                parent = parent.Parent;
            }

            return result;
        }

        /// <summary>
        /// 获取所有子协议
        /// </summary>
        /// <returns></returns>
        public IEnumerable<AbsField> GetChildrenField()
        {
            IList<AbsField> result = new List<AbsField>();
            if (this.CanHasChildren)
            {
                foreach (XElement child in this.XmlElement.Elements("field"))
                {
                    result.Add(FieldFactory.CreateField(child));
                }
            }

            return result;
        }

        public void RemoveAllChildren()
        {
            this.XmlElement.RemoveNodes();
        }

        public void AddChildField(AbsField field)
        {
            this.XmlElement.Add(field.XmlElement);
        }    

        /// <summary>
        /// 生成序列化代码
        /// </summary>
        /// <returns></returns>
        public abstract string GenerateSerializeCode();

        /// <summary>
        /// 生成反序列化代码
        /// </summary>
        /// <returns></returns>
        public abstract string GenerateDeserializeCode();

        /// <summary>
        /// 是否允许嵌套协议
        /// </summary>
        public abstract bool CanHasChildren { get; }
    }
}
